﻿using CPPEI.Coolzon.Common;
using CPPEI.Coolzon.Data;
using CPPEI.Coolzon.Data.MainServiceData;
using CPPEI.Coolzon.Server.CacheData;
using CPPEI.Coolzon.Service.Contract;
using CPPEI.Coolzon.Service.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CPPEI.Coolzon.Server.ServiceImplement
{
    public class ReqEnterDomainHandler : BaseHandler<ReqEnterDomainData, RespEnterDomainData>
    {
        public ReqEnterDomainHandler()
            : base(Service.Contract.REQUEST_SCENARIO.CONNENT, Service.Contract.REQUEST_COMMAND.CONNECT.ENTERDOMAIN)
        {
        }

        protected override RespEnterDomainData OnHandle(Data.MainServiceData.Request request, ReqEnterDomainData requestData)
        {
            CacheData.ControlDomain[] condomainlist = ServerData.Instance.GetDomainList();

            // 获取控制域
            CacheData.ControlDomain domain = ServerData.Instance.GetDomain(requestData.DomainId);
            if(domain == null)
            {
                RespEnterDomainData result = new RespEnterDomainData()
                {
                    IsSuccess = false,
                    Message = "用户进入失败，域不存在！"
                };
                Logger.ErrorToTag("MainService", string.Format("用户{0}进入域{1}失败，域不存在！", request.Header.UserIdentity, requestData.DomainId));
                return result;
            }
            // 获取客户端对象
            Client client = ServerData.Instance.GetClient(request.Header.UserIdentity);
            if (client == null)
            {
                RespEnterDomainData result = new RespEnterDomainData()
                {
                    IsSuccess = false,
                    Message = "用户进入失败，用户不存在！"
                };
                Logger.Info("MainService", string.Format("用户{0}进入域{1}失败，用户不存在！", request.Header.UserIdentity, requestData.DomainId));
                return result;
            }
            else if (client.AppType != "ConsoleApp")
            {
                // 非控制端进入控制域，直接加入
                domain.AddClient(client);
                // 设置为正在进入域的状态
                client.State = ClientState.EnteringDomain;
                RespEnterDomainData result = new RespEnterDomainData()
                {
                    IsSuccess = true,
                    Message = "用户进入成功！",
                    SolutionName = requestData.SolutionName,
                    SolutionCaption = domain.SolutionCaption,
                    DomainId = domain.Id,
                    DomainCaption = domain.Caption,
                    OperatorIdentity = domain.OperatorIdentity,
                    ViewStateAge = domain.ViewStateAge,
                    ViewStateToken = domain.ViewStateToken,
                    ViewStateSolution = domain.SolutionName
                };
                Logger.Info("MainService", string.Format("用户{0}进入域{1}成功！", request.Header.UserIdentity, requestData.DomainId));
                return result;
            }
            else
            {
                #region 控制端
                // 控制端进入，检查是否已存在控制端
                Client existConsoleClient = null;
                List<Client> clientList = domain.GetClientList();
                for (int index = 0; index < clientList.Count; index++)
                {
                    Client existClient = clientList[index];
                    if (existClient.AppType == "ConsoleApp")
                    {
                        // 已存在控制端
                        existConsoleClient = existClient;
                        break;
                    }
                }

                if (existConsoleClient != null)
                {
                    if (existConsoleClient.Callback != null)
                    {
                        try
                        {
                            ConnectionState conState = existConsoleClient.Callback.TestConnectionState();
                            if (conState.IsSuccess)
                            {
                                RespEnterDomainData result = new RespEnterDomainData()
                                {
                                    IsSuccess = false,
                                    Message = "用户进入失败，已存在控制端！"
                                };
                                Logger.Info("MainService", string.Format("用户{0}进入域{1}失败，已存在控制端！", request.Header.UserIdentity, requestData.DomainId));
                                return result;
                            }
                            else
                            {
                                // 删除无效的控制端
                                Logger.Info("MainService", string.Format("删除控制域中无效的控制端用户{0}进入域{1}成功！", existConsoleClient.UserIdentity, requestData.DomainId));
                                domain.RemoveClient(existConsoleClient);
                                ControlAllDisplayClient(domain);
                                domain.AddClient(client);
                                client.State = ClientState.InDomain;
                                RespEnterDomainData result = new RespEnterDomainData()
                                {
                                    IsSuccess = true,
                                    Message = "用户进入成功！",
                                    SolutionName = requestData.SolutionName,
                                    SolutionCaption = domain.SolutionCaption,
                                    DomainId = domain.Id,
                                    DomainCaption = domain.Caption,
                                    OperatorIdentity = domain.OperatorIdentity,
                                    ViewStateAge = domain.ViewStateAge,
                                    ViewStateToken = domain.ViewStateToken,
                                    ViewStateSolution = domain.SolutionName
                                };
                                Logger.Info("MainService", string.Format("用户{0}进入域{1}成功！", request.Header.UserIdentity, requestData.DomainId));
                                return result;
                            }
                        }
                        catch (Exception ex)
                        {
                            // 删除无效的控制端
                            Logger.Info("MainService", string.Format("控制端:{0}测试连接失败，视为无效终端", existConsoleClient.UserIdentity));
                            Logger.Info("MainService", string.Format("删除控制域中无效的控制端用户{0}进入域{1}成功！", existConsoleClient.UserIdentity, requestData.DomainId));
                            domain.RemoveClient(existConsoleClient);
                            ControlAllDisplayClient(domain);
                            domain.AddClient(client);
                            client.State = ClientState.InDomain;
                            RespEnterDomainData result = new RespEnterDomainData()
                            {
                                IsSuccess = true,
                                Message = "用户进入成功！",
                                SolutionName = requestData.SolutionName,
                                SolutionCaption = domain.SolutionCaption,
                                DomainId = domain.Id,
                                DomainCaption = domain.Caption,
                                OperatorIdentity = domain.OperatorIdentity,
                                ViewStateAge = domain.ViewStateAge,
                                ViewStateToken = domain.ViewStateToken,
                                ViewStateSolution = domain.SolutionName
                            };
                            Logger.Info("MainService", string.Format("用户{0}进入域{1}成功！", request.Header.UserIdentity, requestData.DomainId));
                            return result;
                        }
                    }
                    else
                    {
                        // 删除无效的控制端
                        Logger.Info("MainService", string.Format("删除控制域中无效的控制端用户{0}进入域{1}成功！", existConsoleClient.UserIdentity, requestData.DomainId));
                        domain.RemoveClient(existConsoleClient);
                        ControlAllDisplayClient(domain);
                        domain.AddClient(client);
                        client.State = ClientState.InDomain;
                        RespEnterDomainData result = new RespEnterDomainData()
                        {
                            IsSuccess = true,
                            Message = "用户进入成功！",
                            SolutionName = requestData.SolutionName,
                            SolutionCaption = domain.SolutionCaption,
                            DomainId = domain.Id,
                            DomainCaption = domain.Caption,
                            OperatorIdentity = domain.OperatorIdentity,
                            ViewStateAge = domain.ViewStateAge,
                            ViewStateToken = domain.ViewStateToken,
                            ViewStateSolution = domain.SolutionName
                        };
                        Logger.Info("MainService", string.Format("用户{0}进入域{1}成功！", request.Header.UserIdentity, requestData.DomainId));
                        return result;
                    }
                }
                else
                {
                    ControlAllDisplayClient(domain);
                    domain.AddClient(client);
                    client.State = ClientState.InDomain;
                    RespEnterDomainData result = new RespEnterDomainData()
                    {
                        IsSuccess = true,
                        Message = "用户进入成功！",
                        SolutionName = requestData.SolutionName,
                        SolutionCaption = domain.SolutionCaption,
                        DomainId = domain.Id,
                        DomainCaption = domain.Caption,
                        OperatorIdentity = domain.OperatorIdentity,
                        ViewStateAge = domain.ViewStateAge,
                        ViewStateToken = domain.ViewStateToken,
                        ViewStateSolution = domain.SolutionName
                    };
                    Logger.Info("MainService", string.Format("用户{0}进入域{1}成功！", request.Header.UserIdentity, requestData.DomainId));
                    return result;
                }
                #endregion
            }
        }

        /// <summary>
        /// 控制其他所有展示端
        /// </summary>
        private void ControlAllDisplayClient(CPPEI.Coolzon.Server.CacheData.ControlDomain domain)
        {
            List<CacheData.Client> clientList = domain.GetClientList();

            // 通知各个客户端场景事件
            for (int index = 0; index < clientList.Count; index++)
            {
                CacheData.Client client = clientList[index];
                if (client.Callback != null && client.State == ClientState.InDomain)
                {
                    Service.Contract.RespChangeControlStateEventData changeControlStateResponseData = new Service.Contract.RespChangeControlStateEventData(
                        Service.Contract.ControlState.UnderControl,
                        client.UserIdentity,
                        domain.SolutionName,
                        domain.Id);

                    Response response = new Response();
                    response.Header = new ResponseHeader();
                    response.Data = SerializeUtility.SerializeToBinary(changeControlStateResponseData);
                    response.Header.Scenario = Service.Contract.RESPONSE_SCENARIO.SETTING;
                    response.Header.Command = Service.Contract.RESPONSE_COMMAND.SETTING.CHANGECONTROLSTATE;
                    response.Header.SendTicks = DateTime.Now.Ticks;
                    response.Header.DataLength = response.Data.Length;
                    try
                    {
                        client.Callback.OnReceiveResponse(response);
                    }
                    catch
                    {
                        client.Callback = null;
                    }
                }
            }
        }
    }
}
